/*
Automatic clinic tests using a robot arm.
Copyright (C) 2010  CIC-CPC, CHU Gabriel Montpied
All other trademarks, logos and copyrights are the property
of their respective owners.

This file is part of cpc-painbot.

cpc-painbot is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

cpc-painbot is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with cpc-painbot.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "rack.h"

#include <QFile>
#include <QXmlStreamReader>
#include <QDebug>

#include "filament.h"

Rack *Rack::charger(QIODevice *fichier, QObject *parent)
{
    Q_ASSERT(fichier != 0);
    Q_ASSERT(fichier->isOpen());
    Q_ASSERT(fichier->isReadable());

    Rack *rack = 0;


    QXmlStreamReader xml(fichier);

    // Lecture du premier élément, pour s'assurer que c'est un rack.
    if (xml.readNextStartElement()) {
        if (xml.name() == "rack"
            && xml.attributes().hasAttribute("nom")
            && xml.attributes().hasAttribute("hauteur")
            && xml.attributes().hasAttribute("espacement")) {

            rack = new Rack(parent);
            int emplacement = -1;
            bool erreur = false;

            // Attributs du rack.
            rack->setNom(xml.attributes().value("nom").toString());
            rack->setHauteur(xml.attributes().value("hauteur").toString().toDouble());
            rack->setEspacement(xml.attributes().value("espacement").toString().toDouble());

            while (xml.readNextStartElement() && !erreur) {
                if (xml.name() == "description") {
                    qDebug() << "Rack::charger : description";
                    rack->setDescription(xml.readElementText());
                } else if (xml.name() == "position") {
                    PositionBras *position = PositionBras::charger(&xml, rack);
                    Q_CHECK_PTR(position);
                    erreur = (position == 0);
                    if (!erreur)
                        rack->setPosition(position);
                } else if (xml.name() == "emplacement") {
                    qDebug() << "Rack::charger : emplacement";
                    emplacement = xml.attributes().value("numero").toString().toInt();
                } else if (xml.name() == "filament" && emplacement >= 0) {
                    qDebug() << "Rack::charger : filament";
                    Filament *filament = Filament::charger(&xml, rack);
                    Q_CHECK_PTR(filament);
                    erreur = (filament == 0);
                    if (!erreur) {
                        PositionBras pos = *rack->position();
                        pos.setParent(filament);

                        pos.deltaX((emplacement - 1) * rack->espacement());
                        pos.setZ(rack->hauteur());

                        filament->setPosition(pos);

                        rack->ajouter(emplacement, filament);

                        // Calcul de la position du filament !

                        emplacement = -1;
                    }
                    xml.skipCurrentElement(); // Atteint la fin de l'élément emplacement
                }
            }

            if (erreur) {
                qWarning() << "Rack::charger : Erreur au chargement (fichier mal formatté).";
                rack->deleteLater();
                rack = 0;
            }
        }
    }

    return rack;
}

bool Rack::sauver(const Rack *rack, const QIODevice *fichier)
{
    Q_ASSERT(rack != 0);
    Q_ASSERT(fichier != 0);
    Q_ASSERT(fichier->isOpen());
    Q_ASSERT(fichier->isWritable());

    bool ok = false;

    qWarning("Rack::sauver : Pas encore implemente.");

    return ok;
}

Rack::Rack(QObject *parent) :
        QObject(parent)
{
}
